home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / xlib06p1.zip / XMOUSE.CPP < prev    next >
C/C++ Source or Header  |  1995-03-15  |  9KB  |  360 lines

  1. #include "xinternl.h"
  2. #include <i86.h>
  3. #include <mem.h>
  4. #include <conio.h>
  5. /*==================================================================
  6. XMOUSE.CPP contains the basic setup variables and functions for the
  7. XLIB mouse handler.
  8.  
  9. These routines were written initially by Themie Gouthas and
  10. company and modified March 1995 by Victor B. Putz.
  11. ===================================================================*/
  12.  
  13. int MouseInstalled;   /* Indicates whether mouse handler installed */
  14. int MouseHidden;      /* Indicates whether mouse cursor is hidden  */
  15. int MouseButtonStatus;/* Holds the mouse button status             */
  16. int MouseX;           /* Current X position of mouse cursor        */
  17. int MouseY;           /* Current Y position of mouse cursor        */
  18. BYTE MouseFrozen;      /* Disallows position updates if TRUE        */
  19. xColor_t MouseColor;       /* The mouse cursors colour                  */
  20.  
  21. BYTE InitMouseDef[] = {
  22.   0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff,
  23.   0x1f, 0x1b, 0x31, 0x30, 0x60, 0x60
  24. };
  25.  
  26. BYTE MouseMask[ 168 ];
  27.  
  28. BYTE * pbOldHandler = NULL;
  29. int OldX = 0;
  30. int OldY = 0;
  31. int OldScrnOffs = 0;
  32. int BGSaveOffs = 0;
  33.  
  34. static void _loadds far MouseHandler( int, int, int, int );
  35.  
  36. BYTE InHandler = 0;
  37.  
  38. int MouseButtonCount = 0;
  39.  
  40. extern BYTE * pbVGABuffer;
  41. extern int NonVisual_Offs;
  42. extern int VisiblePageOffs;
  43. extern int ScrnLogicalPixelWidth;
  44. extern int ScrnLogicalByteWidth;
  45. extern int ScrnPhysicalPixelWidth;
  46. extern int ScrnPhysicalHeight;
  47. extern int ScrnLogicalHeight;
  48.  
  49. void x_define_mouse_cursor(    /* Define and set a cursor shape      */
  50.   char * MouseDef,
  51.   xColor_t color
  52. )
  53. {
  54.   if ( !MouseInstalled ) {
  55.     return;
  56.   }
  57.   MouseColor = color;
  58.   //now set up storage for all pixel alignments of mouse cursor
  59.   BYTE * pbSource = ( BYTE * )MouseDef;
  60.   BYTE * pbDest = MouseMask;
  61.   //loop for each pixel alignment ( i = alignment )
  62.   for( int iAlignment = 0; iAlignment < 4; ++iAlignment ) {
  63.     pbSource = (BYTE *)MouseDef;
  64.     for( int iRowLoop = 0; iRowLoop < 14; ++iRowLoop ) {
  65.       int iTemp = *pbSource++;
  66.       iTemp <<= iAlignment;
  67.       *pbDest++ = ( BYTE )( iTemp & 0x0f );
  68.       *pbDest++ = ( BYTE )(( iTemp >> 4 ) & 0x0f);
  69.       *pbDest++ = ( BYTE )(( iTemp >> 8 ) & 0x0f);
  70.     }
  71.   }
  72.  
  73. }
  74.  
  75. void x_mouse_init(
  76.   void
  77. )
  78. {
  79.   union REGPACK regs;
  80.   memset( ®s, 0, sizeof( regs ) );
  81.   if ( MouseButtonCount == 0 ) {
  82.     //set up ax with mouse initialization command
  83.     regs.w.ax = 0;
  84.     intr( 0x33, ®s ); //mouse interrupt
  85.     int iIsMouse = regs.w.ax;
  86.     if ( iIsMouse ) {
  87.       MouseButtonCount = regs.w.bx;
  88.     }
  89.     }
  90.     MouseInstalled = regs.w.ax;
  91.   if ( !MouseInstalled ) {
  92.         return;
  93.   }
  94.   //update memory positions to make space to save the mouse backgnd
  95.   BGSaveOffs = NonVisual_Offs;
  96.   NonVisual_Offs += 14*3;
  97.   //hide cursor
  98.   regs.w.ax = 0x02;
  99.   intr( 0x33, ®s );
  100.   MouseInstalled = TRUE;
  101.   //set min/max horizontal position
  102.   regs.w.ax = 0x07;
  103.   regs.w.cx = 0;
  104.   //multiply right edge by 2 since cursor steps by 2 pixels...
  105.   regs.w.dx = ( WORD )( ScrnPhysicalPixelWidth * 2 );
  106.   intr( 0x33, ®s );
  107.   //set min/max vertical position
  108.   regs.w.ax = 0x08;
  109.   regs.w.cx = 0;
  110.   regs.w.dx = ( WORD )ScrnPhysicalHeight;
  111.   intr( 0x33, ®s );
  112.   //get mouse position and button status
  113.   regs.w.ax = 0x03;
  114.   intr( 0x33, ®s );
  115.   MouseY = regs.w.dx;
  116.   MouseX = regs.w.cx;
  117.   //now define our event handler ( this is where it gets edgy )
  118.   regs.w.ax = 0x0c;
  119.   regs.w.cx = 0x1f;     //since we handle all events
  120.   regs.x.edx = FP_OFF( &MouseHandler );
  121.   regs.w.es = FP_SEG( &MouseHandler );
  122.   intr( 0x33, ®s );
  123.   //set up initial mouse state
  124.   MouseHidden = TRUE;
  125.   x_define_mouse_cursor( ( char * )InitMouseDef, regs.x.ds );
  126. }
  127.  
  128. /*
  129. RestoreBg() restores the stored cursor background
  130. */
  131. void RestoreBg(
  132.     xPageHandle_t iOffset,
  133.     xScreenCoord_t iX,
  134.   xScreenCoord_t iY
  135. )
  136. {
  137.     BYTE * pbDest = pbVGABuffer + ( iY * ScrnLogicalByteWidth ) + iX / 4 + iOffset;
  138.   BYTE * pbSource = pbVGABuffer + BGSaveOffs;
  139.     int iSkip = ScrnLogicalByteWidth - 3;
  140.   outpw( GC_INDEX, BIT_MASK );
  141.   outp( SC_INDEX, MAP_MASK );
  142.   outp( SC_INDEX + 1, 0x0f );
  143.   for ( int i = 14; i != 0; --i ) {
  144.     //copy the data
  145.     *pbDest++ = *pbSource++;
  146.     *pbDest++ = *pbSource++;
  147.     *pbDest++ = *pbSource++;
  148.     pbDest += iSkip;
  149.   }
  150.   outp( GC_INDEX + 1, 0x0ff );
  151. }
  152.  
  153. /*
  154. GetBg() gets the background and stores it to the saved area.
  155. */
  156. void GetBg(
  157.     xPageHandle_t iOffset,
  158.     xScreenCoord_t iX,
  159.   xScreenCoord_t iY
  160. )
  161. {
  162.     BYTE * pbSource = pbVGABuffer + ( iY * ScrnLogicalByteWidth ) + iX / 4 + iOffset;
  163.   BYTE * pbDest = pbVGABuffer + BGSaveOffs;
  164.     int iSkip = ScrnLogicalByteWidth - 3;
  165.   outpw( GC_INDEX, BIT_MASK );
  166.   outp( SC_INDEX, MAP_MASK );
  167.   outp( SC_INDEX + 1, 0x0f );
  168.   for ( int i = 14; i != 0; --i ) {
  169.     //copy the data
  170.     *pbDest++ = *pbSource++;
  171.     *pbDest++ = *pbSource++;
  172.     *pbDest++ = *pbSource++;
  173.     pbSource += iSkip;
  174.   }
  175.   outp( GC_INDEX + 1, 0x0ff );
  176. }
  177.  
  178.  
  179.  
  180. void x_hide_mouse(
  181.     void
  182. )
  183. {
  184.   if ( !MouseInstalled || MouseHidden ) {
  185.     return;
  186.   }
  187.   while( InHandler ) {
  188.     NULL;
  189.   }
  190.   MouseHidden = TRUE;
  191.   RestoreBg( OldScrnOffs, OldX, OldY );
  192. }
  193.  
  194. void x_mouse_remove(
  195.     void
  196. )
  197. {
  198.     if ( !MouseInstalled ) {
  199.     return;
  200.   }
  201.   union REGPACK regs;
  202.   memset( ®s, 0, sizeof( regs ) );
  203.   regs.w.ax = 12;       //install event handler
  204.   regs.w.cx = 0;        //disable all events
  205.   intr( 0x33, ®s );
  206. }
  207.  
  208. void x_position_mouse(         /* Set the mouse position             */
  209.   xScreenCoord_t x,
  210.   xScreenCoord_t y);
  211.  
  212. void x_put_cursor(             /* Draw the mouse cursor (NOT FOR     */
  213.   xScreenCoord_t iX,               /* general use)                       */
  214.   xScreenCoord_t iY,
  215.   xScreenCoord_t iTopClip,
  216.   xScreenCoord_t iBotClip,
  217.   xPageHandle_t ScrnOff
  218. )
  219. {
  220.   int iLinesToDisplay = 14;
  221.   int iTemp = iTopClip - iY;
  222.   int iStartY = iY;
  223.     int iStartSourceY = 0;
  224.   //check top clipping
  225.   if ( iTemp > 0 ) {
  226.     if ( iTemp > iLinesToDisplay ) {
  227.       return;
  228.     }
  229.     else {
  230.       iLinesToDisplay -= iTemp;
  231.       iStartSourceY = iTemp;
  232.       iStartY = iTopClip;
  233.     }
  234.   }
  235.   //check bottom clipping
  236.   iTemp = iStartY + iLinesToDisplay - iBotClip;
  237.   if ( iTemp > 0 ) {
  238.     iLinesToDisplay -= iTemp;
  239.   }
  240.   if ( iLinesToDisplay < 0 ) {
  241.     return;
  242.   }
  243.   //now draw this fella
  244.   BYTE * pbDest = pbVGABuffer + ScrnOff + ( iStartY * ScrnLogicalByteWidth ) + iX / 4;
  245.   int iSkip = ScrnLogicalByteWidth - 3;
  246.   BYTE * pbSource = MouseMask + ( 42 * ( iX & 3 ) ) + iStartSourceY * 3;
  247.   outp( SC_INDEX, MAP_MASK );
  248.   while ( iLinesToDisplay-- ) {
  249.     for ( int i = 3; i != 0; --i ) {
  250.         outp( SC_INDEX + 1, *pbSource++ );
  251.         *pbDest++ = ( BYTE )MouseColor;
  252.     }
  253.     pbDest += iSkip;
  254.   }
  255. }
  256.  
  257.  
  258.  
  259. void x_show_mouse(
  260. void
  261. )
  262. {
  263.   if ( !MouseInstalled || !MouseHidden ) {
  264.     return;
  265.   }
  266.   while ( InHandler ) {
  267.     NULL;
  268.   }
  269.   MouseHidden = FALSE;
  270.   OldScrnOffs = VisiblePageOffs;
  271.   OldX = MouseX;
  272.   OldY = MouseY;
  273.   GetBg( OldScrnOffs, OldX, OldY );
  274.   x_put_cursor( OldX, OldY, 0, ScrnLogicalHeight, VisiblePageOffs );
  275. }
  276.  
  277.  
  278. void x_mouse_window(
  279.     xScreenCoord_t x0,     /* Define a mouse window */
  280.   xScreenCoord_t y0,
  281.   xScreenCoord_t x1,
  282.   xScreenCoord_t y1);
  283.  
  284.  
  285. /*
  286. UpdateCursor() updates the cursor position
  287. */
  288. void UpdateCursor(
  289.   void
  290. )
  291. {
  292.   RestoreBg( OldScrnOffs, OldX, OldY );
  293.   OldScrnOffs = VisiblePageOffs;
  294.   OldX = MouseX;
  295.   OldY = MouseY;
  296.   GetBg( VisiblePageOffs, MouseX, MouseY );
  297.   x_put_cursor( MouseX, MouseY, 0, ScrnPhysicalHeight, VisiblePageOffs );
  298. }
  299.  
  300.  
  301. void x_update_mouse(
  302.   void
  303. )
  304. {
  305.     if ( !MouseInstalled || MouseHidden ) {
  306.     return;
  307.   }
  308.   union REGPACK regs;
  309.   memset( ®s, 0, sizeof( regs ) );
  310.   regs.w.ax = 0x03;
  311.   intr( 0x33, ®s );
  312.   MouseY = regs.w.dx;
  313.   MouseX = regs.w.cx;
  314.   MouseButtonStatus = regs.w.bx;
  315.   UpdateCursor();
  316. }
  317.  
  318.  
  319.  
  320. void far * GetStack( void );
  321. void SetStack( void far * );
  322.  
  323. #pragma aux           GetStack = "mov dx,ss" \
  324.     "mov eax,esp" value [ dx eax ];
  325. #pragma aux           SetStack = "mov ss,dx" \
  326.     "mov esp,eax" parm [ dx eax ];
  327.  
  328.  
  329. #pragma aux           MouseHandler parm [ ecx ] [ edx ] [ ebx ] [ eax ]
  330.  
  331. #define STACKSIZE 1024
  332.  
  333. static void _loadds far MouseHandler(
  334.     int iX,
  335.     int iY,
  336.   int iButtonStatus,
  337.   int iMotionEvent
  338. )
  339. {
  340.     if ( InHandler ) {
  341.     return;
  342.   }
  343.   static char         newstack[ STACKSIZE ];
  344.   static void far     *oldstack;
  345.   InHandler = 1;
  346.   MouseButtonStatus = iButtonStatus;
  347.   if ( iMotionEvent & 1 ) {
  348.     MouseX = iX / 2;
  349.     MouseY = iY;
  350.     if ( ( !MouseHidden ) && ( !MouseFrozen ) ) {
  351.       oldstack = GetStack();
  352.       SetStack( newstack + STACKSIZE );
  353.       UpdateCursor();
  354.       SetStack( oldstack );
  355.     }
  356.   }
  357.   InHandler = 0;
  358. }
  359.  
  360.